package com.mo.service.impl;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mo.constant.Constants;
import com.mo.mapper.TPermissionmapper;
import com.mo.mapper.TRolemapper;
import com.mo.mapper.TUsermapper;
import com.mo.model.TPermission;
import com.mo.model.TRole;
import com.mo.model.TUser;
import com.mo.query.BaseQuery;
import com.mo.query.UserQuery;
import com.mo.service.UserService;
import com.mo.util.CacheUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mo
 * version
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private TUsermapper tUsermapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private TRolemapper tRolemapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private TPermissionmapper tPermissionmapper;


    private  ObjectMapper objectMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        TUser tUser = tUsermapper.selectByLoginAct(username);
        if (tUser == null) {
            throw new UsernameNotFoundException("登陆账号不存在");
        }

        List<TRole> tRoleList = tRolemapper.selectByUserId(tUser.getId());
        ArrayList<String> stringRoleList = new ArrayList<>();
        for (TRole tRole : tRoleList) {
            stringRoleList.add(tRole.getRole());
        }
        tUser.setRoleList(stringRoleList);
        //将对象返回给框架，框架会 .usernameParameter("loginAct")
        //                    .passwordParameter("loginPwd")来校验的

        //查询一下该用户有哪些菜单
        List<TPermission> menuPermissionList = tPermissionmapper.selectMenuPermissionByUserId(tUser.getId());
        tUser.setMenuPermissionList(menuPermissionList);

        //查询一下该用户有哪些功能权限
        List<TPermission> buttonPermission = tPermissionmapper.selectButtonPermissionByUserId(tUser.getId());
        ArrayList<String> stringPermissionList = new ArrayList<>();
        buttonPermission.forEach(tPermission -> {
            //往stringPermissionList属性添加权限标识，框架会调用的
            stringPermissionList.add(tPermission.getCode());
        });
        tUser.setPermissionList(stringPermissionList);
        return tUser;
    }

    @Override
    public PageInfo<TUser> getUserByPage(Integer current) {
        //设置PageHelper
        PageHelper.startPage(current, Constants.PAGE_SIZE);
        //查询
        List<TUser> list = tUsermapper.selectUserByPage(BaseQuery.builder().build());
        PageInfo<TUser> info = new PageInfo<>(list);
        return info;
    }

    @Override
    public TUser getUserDetailById(Integer id) {
        return tUsermapper.selectDetailById(id);
    }

    /*保存编辑用户*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveUserQuery(UserQuery userQuery) {
        TUser tUser = new TUser();
        BeanUtils.copyProperties(userQuery, tUser);
        tUser.setLoginPwd(passwordEncoder.encode(userQuery.getLoginPwd()));//密码加密
        tUser.setCreateTime(new Date());
        //security的安全上下文获取
        TUser user = (TUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        tUser.setCreateBy(user.getId());
        return tUsermapper.insertSelective(tUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(UserQuery userQuery) {
        TUser tUser = new TUser();
        BeanUtils.copyProperties(userQuery, tUser);
        if (StringUtils.hasText((userQuery.getLoginPwd()))) {
            tUser.setLoginPwd(passwordEncoder.encode(userQuery.getLoginPwd()));//密码加密
        }
        tUser.setEditTime(new Date());
        //security的安全上下文获取
        TUser user = (TUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        tUser.setEditBy(user.getId());
        return tUsermapper.updateByPrimaryKeySelective(tUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserById(Integer id) {
        return tUsermapper.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDelUserByIds(List<String> idList) {
        return tUsermapper.deleteByIds(idList);
    }

    @Override
    public List<TUser> getOwnerList() {
        return CacheUtils.getCacheData(() -> {
                    //生产，从缓存redis查询数据
                    List<String> userList=stringRedisTemplate.opsForList().range(Constants.REDIS_OWNER_KEY,0,-1);
                   return userList.stream().map( user->{ return JSONUtil.toBean(user,TUser.class);}).collect(Collectors.toList());
                },
                () -> {
                    //生产，从mysql查询数据
                    return tUsermapper.selectByOwner();
                },
                (t) -> {
                    List<String> jsonList= t.stream().map(user->{
                    return JSONUtil.toJsonStr(user);
                }).collect(Collectors.toList());
                    stringRedisTemplate.opsForList().leftPushAll(Constants.REDIS_OWNER_KEY,  jsonList);
                }
        );
    }

    @Override
    public String selectPasswordById(Integer id) {
       return tUsermapper.selectPasswordById(id);
    }

    @Override
    public int updatePassword(TUser user) {
        return tUsermapper.updateByPrimaryKeySelective(user);
    }
}
